﻿using System.Net;
#if NET461
using System.Net.Http;
#endif

namespace OkFlurl
{
    internal class FlurlProgressFile : HttpContent
    {
        private readonly string _path;
        private readonly FlurlForm _form;
        private readonly string _fileName;

        public FlurlProgressFile(string path, FlurlForm form, string fileName)
        {
            _path = path;
            _form = form;
            _fileName = fileName;
        }

        protected override async Task SerializeToStreamAsync(Stream stream, TransportContext? context)
        {
            using var fs = new FileStream(_path, FileMode.Open, FileAccess.Read, FileShare.None, _form.UploadBufferSize, useAsync: true);
            if (_form.UploadProgress == null)
            {
                await fs.CopyToAsync(stream, _form.UploadBufferSize, _form.Token);
            }
            else
            {
                _form.UploadProgress.FileName = _fileName;
                int currentRead;
                var buffer = new byte[_form.UploadBufferSize];
                do
                {
                    _form.Token.ThrowIfCancellationRequested();

                    if (_form.UploadProgress.IsStop)
                    {
                        await _form.UploadProgress.WaitAsync();
                    }

#if NET461 || NETSTANDARD2_0
                    currentRead = await fs.ReadAsync(buffer, 0, buffer.Length, _form.Token).ConfigureAwait(false);
#else
                    currentRead = await fs.ReadAsync(buffer, _form.Token);
#endif
                    if (currentRead > 0)
                    {
                        _form.UploadCurrSize += currentRead;

#if NET461 || NETSTANDARD2_0
                        await stream.WriteAsync(buffer, 0, currentRead, _form.Token).ConfigureAwait(false);
#else
                        await stream.WriteAsync(buffer.AsMemory(0, currentRead), _form.Token);
#endif
                        await stream.FlushAsync(_form.Token); //及时释放，把数据传递到服务器

                        _form.ChangeUploadSize();
                    }

                } while (currentRead > 0);
            }
        }

        protected override bool TryComputeLength(out long length)
        {
            length = -1;
            return false;
        }
    }
}
